#include "voidqueue.h"

void voidQueueInit(struct arrayQueueManagerStruct *quearray, uint32_t quesize)
{
    if(quearray == NULL)
    {
        logerror("");
        return;
    }
    pthread_mutex_init(&quearray->quelock, NULL);
    quearray->quedata = malloc(sizeof(void *) * quesize);
    quearray->quesize = 0;
    if(quearray->quedata == NULL)
    {
        logerror("");
        return;
    }
    quearray->quesize = quesize;
    quearray->writeid = 0;
    quearray->readid = 0;
}

int voidQueueFree(struct arrayQueueManagerStruct *quearray)
{
    if(quearray == NULL)
    {
        logerror("");
        return -1;
    }
    if(voidQueueCount(quearray) > 0)
    {
        logwarn("warniong:que buffer has data! please free them first!");
        return -1;
    }
    pthread_mutex_lock(&quearray->quelock);
    if(quearray->quedata)
    {
        free(quearray->quedata);
    }
    quearray->quesize = 0;
    quearray->writeid = 0;
    quearray->readid = 0;
    pthread_mutex_unlock(&quearray->quelock);
    pthread_mutex_destroy(&quearray->quelock);
    return 0;
}

//容器已写入的数量。
uint32_t voidQueueCount(struct arrayQueueManagerStruct *quearray)
{
    if(quearray == NULL)
    {
        logerror("");
        return 0;
    }
    // 只读，可以不加锁，写才加
    return (quearray->writeid + quearray->quesize - quearray->readid) % quearray->quesize;
}

//容器剩余的数量。
uint32_t voidQueueRemain(struct arrayQueueManagerStruct *quearray)
{
    if(quearray == NULL)
    {
        logerror("");
        return 0;
    }
    // 只读，可以不加锁，写才加
    return quearray->quesize - voidQueueCount(quearray) - 1;
}

int voidQueuePush(struct arrayQueueManagerStruct *quearray, void *indata)
{
    int tmpflag = -1;
    if(!(quearray != NULL && indata != NULL && quearray->quedata != NULL))
    {
        logerror("");
        return -1;
    }
    pthread_mutex_lock(&quearray->quelock);
    do
    {
        if(voidQueueRemain(quearray) < 1)
        {
            logwarn("buffer over");
            tmpflag = -1;
            break;
        }
        quearray->quedata[quearray->writeid] = indata;
        quearray->writeid = CYCLE_ADD(quearray->writeid, 1, quearray->quesize);
        tmpflag = 1;
    } while (0);
    // 释放公共资源方式.还有goto
    pthread_mutex_unlock(&quearray->quelock);    
    return tmpflag;
}

int voidQueuePop(struct arrayQueueManagerStruct *quearray, void **outdata)
{
    int tmpflag = -1;
    if(!(quearray != NULL && outdata != NULL && quearray->quedata != NULL))
    {
        logerror("");
        return -1;
    }
    pthread_mutex_lock(&quearray->quelock);
    if(voidQueueCount(quearray) < 1)
    {
        logerror("buffer empty");
        tmpflag = -1;
        goto popFinishPoint;
    }
    outdata[0] = quearray->quedata[quearray->readid];
    quearray->readid = CYCLE_ADD(quearray->readid, 1, quearray->quesize);
    tmpflag = 1;
    //goto 主要用于释放公共资源。
popFinishPoint:
    pthread_mutex_unlock(&quearray->quelock);
    return tmpflag;
}

